package com.chessgame.controller;

import com.chessgame.model.Board;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 游戏控制器，负责管理游戏状态、计时器和存档
 */
public class GameController {
    private Board board;
    private Timer redTimer;
    private Timer blackTimer;
    private int redTimeSeconds;
    private int blackTimeSeconds;
    private boolean isPaused;
    private GameStateListener gameStateListener;

    public GameController() {
        board = new Board();
        redTimeSeconds = 0;
        blackTimeSeconds = 0;
        isPaused = false;
        initializeTimers();
    }

    private void initializeTimers() {
        redTimer = new Timer(true);
        blackTimer = new Timer(true);

        TimerTask redTask = new TimerTask() {
            @Override
            public void run() {
                if (!isPaused && board.isRedTurn()) {
                    redTimeSeconds++;
                    if (gameStateListener != null) {
                        gameStateListener.onTimerUpdate(true, redTimeSeconds);
                    }
                }
            }
        };

        TimerTask blackTask = new TimerTask() {
            @Override
            public void run() {
                if (!isPaused && !board.isRedTurn()) {
                    blackTimeSeconds++;
                    if (gameStateListener != null) {
                        gameStateListener.onTimerUpdate(false, blackTimeSeconds);
                    }
                }
            }
        };

        redTimer.scheduleAtFixedRate(redTask, 0, 1000);
        blackTimer.scheduleAtFixedRate(blackTask, 0, 1000);
    }

    public void setGameStateListener(GameStateListener listener) {
        this.gameStateListener = listener;
    }

    public boolean movePiece(int fromX, int fromY, int toX, int toY) {
        boolean moveSuccess = board.movePiece(fromX, fromY, toX, toY);
        if (moveSuccess && gameStateListener != null) {
            gameStateListener.onBoardUpdate();
            boolean isRedTurn = board.isRedTurn();
            if (board.isInCheck(isRedTurn)) {
                if (board.isCheckmate(isRedTurn)) {
                    gameStateListener.onGameOver(!isRedTurn);
                } else {
                    gameStateListener.onCheck(isRedTurn);
                }
            }
        }
        return moveSuccess;
    }

    public boolean undoMove() {
        boolean undoSuccess = board.undoLastMove();
        if (undoSuccess && gameStateListener != null) {
            gameStateListener.onBoardUpdate();
        }
        return undoSuccess;
    }

    public void pauseGame() {
        isPaused = true;
        if (gameStateListener != null) {
            gameStateListener.onGamePaused();
        }
    }

    public void resumeGame() {
        isPaused = false;
        if (gameStateListener != null) {
            gameStateListener.onGameResumed();
        }
    }

    public void saveGame(File file) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode gameState = mapper.createObjectNode();
        gameState.put("redTimeSeconds", redTimeSeconds);
        gameState.put("blackTimeSeconds", blackTimeSeconds);
        gameState.put("isRedTurn", board.isRedTurn());
        
        // TODO: 保存棋盘状态
        // 这里需要实现棋盘状态的序列化

        mapper.writeValue(file, gameState);
    }

    public void loadGame(File file) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode gameState = mapper.readValue(file, ObjectNode.class);
        
        redTimeSeconds = gameState.get("redTimeSeconds").asInt();
        blackTimeSeconds = gameState.get("blackTimeSeconds").asInt();
        
        // TODO: 加载棋盘状态
        // 这里需要实现棋盘状态的反序列化

        if (gameStateListener != null) {
            gameStateListener.onBoardUpdate();
            gameStateListener.onTimerUpdate(true, redTimeSeconds);
            gameStateListener.onTimerUpdate(false, blackTimeSeconds);
        }
    }

    public Board getBoard() {
        return board;
    }

    public boolean isPaused() {
        return isPaused;
    }

    public int getRedTimeSeconds() {
        return redTimeSeconds;
    }

    public int getBlackTimeSeconds() {
        return blackTimeSeconds;
    }

    public void cleanup() {
        if (redTimer != null) {
            redTimer.cancel();
            redTimer = null;
        }
        if (blackTimer != null) {
            blackTimer.cancel();
            blackTimer = null;
        }
    }

    /**
     * 游戏状态监听器接口
     */
    public interface GameStateListener {
        void onBoardUpdate();
        void onTimerUpdate(boolean isRed, int seconds);
        void onGamePaused();
        void onGameResumed();
        void onCheck(boolean isRedInCheck);
        void onGameOver(boolean redWins);
    }
}